package be.ipl.finito.domaine;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Transient;
import javax.persistence.UniqueConstraint;

import be.ipl.finito.util.Util;

@SuppressWarnings("serial")
@Entity
@Table(schema = "FINITO", name = "GRILLES", uniqueConstraints={@UniqueConstraint(columnNames={"JOUEUR_ID", "PARTIE_ID"})})
public class Grille implements Serializable {

	@Id
	@Column(name="GRILLE_ID")
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	private int id;
	
	@ManyToOne
	@JoinColumn(name = "JOUEUR_ID")
	private Joueur joueur;

	@OneToMany
	@JoinColumn(name = "GRILLE_ID")
	private List<Case> grille = new ArrayList<Case>(12);
	
	@Transient
	private List<Jeton> jetons = new ArrayList<Jeton>(3);

	@Transient
	private int score;
	
	protected Grille() {

	}

	public Grille(Joueur joueur) {
		this.joueur = joueur;
	}

	public int calculerScore() {
		Collections.sort(grille, new Comparator<Case>() {
			@Override
			public int compare(Case c1, Case c2) {
				return c1.getNumeroCase() - c2.getNumeroCase();
			}
		});

		List<Integer> scores = new ArrayList<Integer>();
		int score = 1;
		
		Jeton precedent = grille.get(0).getJeton();
		
		
		for (int i = 1; i < 12; i++) {
			Jeton j = grille.get(i).getJeton();
			if(j.getNumero() > precedent.getNumero()){
				score++;
			}else{
				scores.add(score);
				score = 1;
			}
			precedent = j;
		}
		scores.add(score);

		Collections.sort(scores, new Comparator<Integer>() {
			@Override
			public int compare(Integer o1, Integer o2) {
				return o2-o1;
			}
		});
		return scores.get(0);
	}
	
	public boolean ajouterJeton(Jeton jeton){
		return this.jetons.add(jeton);
	}
	
	public boolean supprimerJeton(Jeton jeton){
		return this.jetons.remove(jeton);
	}
	
	public boolean placerJeton(Case c){
		Util.checkObject(c);
		this.jetons.remove(c.getJeton());
		return this.grille.add(c);
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public Joueur getJoueur() {
		return joueur;
	}

	public void setJoueur(Joueur joueur) {
		this.joueur = joueur;
	}

	public List<Case> getGrille() {
		return grille;
	}

	public void setGrille(List<Case> grille) {
		this.grille = grille;
	}

	public List<Jeton> getJetons() {
		System.out.println();
		
		System.out.println("Grille getJeton " + joueur.getLogin());
		System.out.println(jetons.toString());
		System.out.println();
		System.out.println("===============");
		return jetons;
	}

	public void setJetons(List<Jeton> jetons) {
		this.jetons = jetons;
	}

	public int getScore() {
		return score;
	}

	public void setScore(int score) {
		this.score = score;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + id;
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Grille other = (Grille) obj;
		if (id != other.id)
			return false;
		return true;
	}
}